home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Amster - Chat
- ** Copyright © 1999-2000 by Gürer Özen
- ** Copyright © 2000-2001 by Jacob Laursen
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 2 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- #include "amster.h"
-
- #include <MUI/NListview_mcc.h>
- #include <MUI/textinput_mcc.h>
-
- #include "chatline.h"
- #include "amster_Cat.h"
-
- channel chat_chans = NULL;
-
- ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg);
- Object *UserlistContextMenuBuild(struct IClass *cl, Object *obj, struct MUIP_NList_ContextMenuBuild *msg);
- MUI_LIST_DISP_DECL(chat_msgdisp, struct ChatMessage *m);
- MUI_LIST_DISP_DECL(userlistdisp, struct ChannelUserData *cud);
- MUI_LIST_DEST_DECL(userlistdest, struct ChannelUserData *cud);
- void channel_part(struct chatdata *data);
- void chat_say(struct chatdata *data, char *user, char *msg);
- void chat_sayf(struct chatdata *data, char *user, char *msg, ...);
- void chat_saysys(struct chatdata *data, char *msg);
- void chat_echo(struct chatdata *data, char *msg);
- void chat_command(struct chatdata *data);
-
- struct MUI_CustomClass *UserlistContext;
-
-
- MUI_DISPATCH(chat_dispatch)
- {
- struct chatdata *data;
-
- switch(msg->MethodID) {
- case OM_NEW:
- return(chat_new(cl, obj, (APTR)msg));
- case OM_DISPOSE:
- {
- channel c = chat_chans;
- data = INST_DATA(cl, obj);
-
- /* Update the linked list of channels */
-
- if (c == &data->chn) {
- chat_chans = c->next;
- /* The one to remove was the first in list,
- so we just point to the next one */
- }
- else while (c) {
- if (c->next == &data->chn)
- c->next = data->chn.next;
- /* The next one is the one to remove, so we point to the next
- one to that */
- c = c->next;
- }
-
- break;
- }
- case CHAT_COMMAND:
- data = INST_DATA(cl, obj);
- chat_command(data);
- return(0);
- case CHAT_JOINCHANNEL:
- data = INST_DATA(cl, obj);
- if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
- else {
- data->chn.name = strdup((char *)(((muimsg)msg)->arg1));
- nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
- data->chn.joinflag = 1;
- }
- return(0);
- case CHAT_JOINACK:
- data = INST_DATA(cl, obj);
- data->chn.joinflag = 2;
- DoMethod(data->rect, MUIM_Group_InitChange);
- set(data->chantxt, MUIA_Text_Contents, data->chn.name);
- DoMethod(data->rect, MUIM_Group_ExitChange);
- chat_sayf(data, "\33b-->", (char *)MSG_CHAT_JOINED_YOU, data->chn.name);
- return(0);
- case CHAT_PUBLICMSGRECV:
- data = INST_DATA(cl, obj);
- if (stricmp(prf->user, (char *)(((muimsg)msg)->arg1)) != 0)
- chat_say(data, (char *)(((muimsg)msg)->arg1), (char *)(((muimsg)msg)->arg2));
- /* Only show messages from others */
- return(0);
- case CHAT_JOINMSG:
- data = INST_DATA(cl, obj);
- chat_sayf(data, "\33b-->", (char *)MSG_CHAT_JOINED_THIS, (char *)(((muimsg)msg)->arg1), (int)(((muimsg)msg)->arg2), nap_linktype[(int)(((muimsg)msg)->arg3)]);
- case CHAT_USERLIST:
- {
- struct ChannelUserData *ud;
- data = INST_DATA(cl, obj);
- if (ud = malloc(sizeof(struct ChannelUserData))) {
- memset(ud, 0, sizeof(struct ChannelUserData));
- ud->Name = strdup((char *)(((muimsg)msg)->arg1));
- ud->Shares = (int)(((muimsg)msg)->arg2);
- ud->Link = (int)(((muimsg)msg)->arg3);
- DoMethod(data->userlist, MUIM_NList_InsertSingle, ud, MUIV_NList_Insert_Bottom);
- }
- return(0);
- }
- case CHAT_USERPART:
- {
- int i;
- struct ChannelUserData *cud;
- data = INST_DATA(cl, obj);
-
- chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_THIS, (char *)(((muimsg)msg)->arg1));
-
- for (i=0; ; i++) {
- DoMethod(data->userlist, MUIM_NList_GetEntry, i, &cud);
- if (!cud) break;
- if (strcmp((char *)(((muimsg)msg)->arg1), cud->Name) == 0) {
- DoMethod(data->userlist, MUIM_NList_Remove, i);
- break;
- }
- }
-
- return(0);
- }
- case CHAT_CHANNELPART:
- data = INST_DATA(cl, obj);
- if (data->chn.name) nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
- DoMethod(gui->iconpanel, PANEL_DISPOSECHAT, obj);
- return(0);
- case CHAT_CHANNELTOPIC:
- data = INST_DATA(cl, obj);
- set(data->topicstr, MUIA_String_Contents, ((muimsg)msg)->arg1);
- return(0);
-
- }
- return(DoSuperMethodA(cl, obj, msg));
- }
-
-
- ULONG chat_new(struct IClass *cl, Object *obj, struct opSet *msg)
- {
- static struct Hook msgdispHook = { {0,0}, &chat_msgdisp, NULL, NULL };
- static struct Hook userlistdispHook = { {0,0}, &userlistdisp, NULL, NULL };
- static struct Hook userlistdestHook = { {0,0}, &userlistdest, NULL, NULL };
-
- struct chatdata *data;
- Object *rect, *chantxt, *topicstr, *msglist, *userlist, *msgstr;
-
- obj = (Object *)DoSuperNew(cl, obj,
- MUIA_HelpNode, "chat",
- MUIA_Window_Title, MSG_CHAT_TITLE,
- MUIA_Window_ID, MAKE_ID('C','H','A','T'),
- WindowContents, VGroup,
- Child, rect = HGroup,
- Child, chantxt = TextObject,
- MUIA_HorizWeight, 0,
- MUIA_Text_Contents, MSG_CHAT_NONEJOINED,
- End,
- Child, topicstr = TextinputObject,
- StringFrame,
- MUIA_Textinput_Multiline, FALSE,
- MUIA_CycleChain, 1,
- End,
- End,
- Child, HGroup,
- Child, NListviewObject,
- MUIA_HorizWeight, 75,
- MUIA_NListview_NList, msglist = NListObject,
- ReadListFrame,
- MUIA_NList_Input, FALSE,
- MUIA_NList_Format, "BAR P=\33r,",
- MUIA_NList_DisplayHook, &msgdispHook,
- MUIA_NList_DefaultObjectOnClick, FALSE,
- MUIA_NList_AutoVisible, TRUE,
- MUIA_NList_AutoCopyToClip, TRUE,
- MUIA_NList_TypeSelect, MUIV_NList_TypeSelect_Char,
- End,
- End,
- Child, BalanceObject, End,
- Child, NListviewObject,
- MUIA_HorizWeight, 25,
- MUIA_NListview_NList, userlist = NewObject(UserlistContext->mcc_Class, NULL,
- /*userlist = NListObject,*/
- InputListFrame,
- MUIA_NList_DefaultObjectOnClick, FALSE,
- /* new */
- MUIA_NList_Format, "",
- MUIA_NList_DisplayHook, &userlistdispHook,
- MUIA_NList_DestructHook, &userlistdestHook,
- /* /new */
- /* old
- MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
- MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
- /old */
- MUIA_CycleChain, 1,
- TAG_DONE),
- End,
- End,
- Child, msgstr = TextinputObject,
- StringFrame,
- MUIA_CycleChain, 1,
- End,
- End,
- TAG_MORE, msg->ops_AttrList);
-
- if (!obj) return(0);
-
- data = INST_DATA(cl,obj);
- data->rect = rect;
- data->chantxt = chantxt;
- data->topicstr = topicstr;
- data->msglist = msglist;
- data->userlist = userlist;
- data->msgstr = msgstr;
-
- data->chn.next = chat_chans;
- chat_chans = &data->chn;
- data->chn.joinflag = 0;
- data->chn.name = NULL;
- data->chn.win = obj;
-
- DoMethod(msgstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, obj, 1, CHAT_COMMAND);
- DoMethod(msgstr, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, obj, 3, MUIM_Set, MUIA_Window_ActiveObject, msgstr);
-
- DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, obj, 1, CHAT_CHANNELPART);
- /* DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, MUIV_Notify_Application, 5, MUIM_Application_PushMethod, gui->iconpanel, 2, PANEL_DISPOSECHAT, obj);*/
-
- return((ULONG)obj);
- }
-
-
- MUI_DISPATCH(UserlistContextDispatcher)
- {
- switch (msg->MethodID)
- {
- case MUIM_NList_ContextMenuBuild:
- return (ULONG) UserlistContextMenuBuild(cl, obj, (struct MUIP_NList_ContextMenuBuild *)msg);
- break;
- case MUIM_ContextMenuChoice:
- {
- int item = muiUserData(((struct MUIP_ContextMenuChoice *)msg)->item);
- switch (item) {
- case 0:
- DoMethod(gui->searchpanel, SEARCH_ADDTOHOTLIST);
- break;
- case 1:
- DoMethod(gui->searchpanel, SEARCH_NICKFROMLIST);
- break;
- }
- return NULL;
- }
- }
- return(DoSuperMethodA(cl, obj, msg));
- }
-
-
- Object *UserlistContextMenuBuild(struct IClass *cl, Object *obj, struct MUIP_NList_ContextMenuBuild *msg)
- {
- struct UserlistContextData *data = INST_DATA(cl, obj);
-
- if (msg->ontop || msg->pos == -1) {
- return NULL; /* Default context menu when pointer isn't on an entry */
- }
- else {
- gContextChoice = msg->pos;
- return (
- MenustripObject,
- Child, MenuObject,
- MUIA_Menu_Title, MSG_MAINCONTEXTMENU_TITLE,
- Child, data->MI_AddToHotlist = MenuitemObject,
- MUIA_Menuitem_Title, MSG_MAINCONTEXTMENU_ADD,
- MUIA_UserData, 0,
- End,
- Child, data->MI_BrowseUser = MenuitemObject,
- MUIA_Menuitem_Title, MSG_MAINCONTEXTMENU_BROWSE,
- MUIA_UserData, 1,
- End,
- End,
- End);
- }
- }
-
-
- MUI_LIST_DISP(chat_msgdisp, struct ChatMessage *m)
- {
- *array++ = m->Nick;
- *array = m->Msg;
-
- return(0);
- }
-
-
- MUI_LIST_DISP(userlistdisp, struct ChannelUserData *cud)
- {
- static char line[64];
-
- sprintf(line, "%s (%ld)", cud->Name, cud->Shares);
- cud->Display = strdup(line);
- *array++ = cud->Display;
- *array = "";
-
- return(0);
- }
-
-
- MUI_LIST_DEST(userlistdest, struct ChannelUserData *cud)
- {
- free(cud->Name);
- free(cud->Display);
- free(cud);
-
- return(0);
- }
-
- void chat_say(struct chatdata *data, char *user, char *msg)
- {
- struct ChatMessage *m;
-
- m = malloc(sizeof(struct ChatMessage));
- if (!m) return;
-
- m->Nick = strdup(user);
- m->Msg = strdup(msg);
-
- DoMethod(data->msglist, MUIM_NList_InsertSingleWrap, m, MUIV_NList_Insert_Bottom, 2, NULL);
- set(data->msglist, MUIA_NList_First, MUIV_NList_Active_Bottom);
- }
-
-
- void chat_sayf(struct chatdata *data, char *user, char *msg, ...)
- {
- static char buf[1024];
- va_list ap;
-
- va_start(ap, msg);
- vsprintf(buf, msg, ap);
- va_end(ap);
- chat_say(data, user, buf);
- }
-
-
- void chat_saysys(struct chatdata *data, char *msg)
- {
- chat_say(data,"\33b***",msg);
- }
-
-
- void chat_echo(struct chatdata *data, char *msg)
- {
- chat_say(data,"\33b»",msg);
- }
-
-
- void chat_command(struct chatdata *data)
- {
- u_long tmp;
- char *com;
-
- GetAttr(MUIA_String_Contents, data->msgstr, &tmp);
- com = (char *)tmp;
-
- DoMethod(data->msgstr, CHATLINE_ADD, com);
-
- if (com[0] == '/') {
- if (strnicmp("join", com+1, 4) == 0 && strlen(com)>6) {
- if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
- else {
- if (data->chn.name) channel_part(data);
- /* Leave channel in this window before joining a new one. */
-
- data->chn.name = strdup(com+6);
- nap_sendbuf(NAPC_CHANNELJOIN, data->chn.name);
- data->chn.joinflag = 1;
- }
- }
- else if (stricmp("leave", com+1) == 0) {
- if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
- else channel_part(data);
- }
- else if (stricmp("list", com+1) == 0) {
- DoMethod(gui->WI_ChannelList, MUIM_Set, MUIA_Window_Open, TRUE);
- if (gui_onlinestate == ONLINE) DoMethod(gui->WI_ChannelList, CHANLIST_UPDATE);
- }
-
- }
- else {
- if (gui_onlinestate < ONLINE) chat_saysys(data, (char *)MSG_CHAT_NOTCONNECTED);
- else {
- if (data->chn.joinflag>1) {
- chat_say(data, prf->user, com);
- sprintf(nap_buf,"%s %s", data->chn.name, com);
- nap_send(NAPC_PUBLICMSGSEND);
- }
- else {
- chat_saysys(data, (char *)MSG_CHAT_NOTJOINED);
- }
- }
- }
-
- set(data->msgstr, MUIA_String_Contents, NULL);
- }
-
-
- void channel_part(struct chatdata *data)
- {
- u_long item;
-
- nap_sendbuf(NAPC_CHANNELPART, data->chn.name);
- chat_sayf(data,"\33b<--", (char *)MSG_CHAT_PART_YOU, data->chn.name);
-
- set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
- while (1) {
- DoMethod(data->userlist, MUIM_NList_GetEntry, 0, &item);
- if (!item) break;
- DoMethod(data->userlist, MUIM_NList_Remove, MUIV_NList_Remove_First);
- }
- set(data->userlist, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
- /* Clear users from list */
-
- data->chn.name = NULL;
- /* Clear channel name */
-
- set(data->chantxt, MUIA_Text_Contents, MSG_CHAT_NONEJOINED);
- /* Set channel name */
- }
-
-
- void chat_interpret(u_int com, char *data)
- {
- channel c;
-
- switch (com) {
- case NAPC_PUBLICMSGRECV:
- c = chat_findchan(nap_token(&data));
- if (!c) break;
- DoMethod(c->win,CHAT_PUBLICMSGRECV,nap_token(&data),data);
- break;
- case NAPC_JOINACK:
- c = chat_findchan(data);
- if (!c) break;
- DoMethod(c->win,CHAT_JOINACK);
- break;
- case NAPC_USERPART:
- c = chat_findchan(nap_token(&data));
- if (!c) break;
- DoMethod(c->win,CHAT_USERPART,nap_token(&data));
- break;
- case NAPC_JOINMSG:
- c = chat_findchan(nap_token(&data));
- if (!c) break;
- DoMethod(c->win, CHAT_JOINMSG, nap_token(&data), nap_itoken(&data), atoi(data));
- break;
- case NAPC_USERLIST:
- c = chat_findchan(nap_token(&data));
- if (!c) break;
- DoMethod(c->win, CHAT_USERLIST, nap_token(&data), nap_itoken(&data), atoi(data));
- break;
- case NAPC_USERLISTEND:
- break;
- case NAPC_CHANNELTOPIC:
- c = chat_findchan(nap_token(&data));
- if (!c) break;
- DoMethod(c->win, CHAT_CHANNELTOPIC, data);
- break;
- }
- }
-
-
- channel chat_findchan(char *name)
- {
- channel c = chat_chans;
-
- while (c) {
- if (stricmp(c->name, name) == 0) return(c);
- c = c->next;
- }
- return(0);
- }
-